#pragma once

#include <CommonLib/Math/Mat33.h>
#include <CommonLib/Math/Mat44.h>
#include <CommonLib/Math/Vec3.h>
#include <CommonLib/Math/Vec3I.h>
#include <CommonLib/Math/Vec4.h>
#include <CommonLib/Math/Vec2.h>
#include <CommonLib/Math/Vec2I.h>
#include <CommonLib/Math/Quat.h>
#include <CommonLib/Math/Plane3.h>
#include <CommonLib/Math/AABB.h>
#include <CommonLib/Math/MathFunctions.h>
#include <CommonLib/Math/Random.h>

namespace fastbird
{
	inline Mat44 MakeViewMatrix(const Vec3& pos, const Vec3& x, const Vec3& y, const Vec3& z)
	{
		// transposed
		Mat33 tansposedRot(
			x.x, x.y, x.z,
			y.x, y.y, y.z,
			z.x, z.y, z.z
			);
		Vec3 t = -(tansposedRot * pos);
		Mat44 viewMat(tansposedRot, t);
		return viewMat;
	}

	//------------------------------------------------------------------------
	// d3d left handed
	inline Mat44 MakeProjectionMatrix(float fov, float aspectRatio, float n, float f)
	{
		const float d = 1.0f/tan(fov/2.f);
		const float DofA = d/aspectRatio;
		float A = f / (f-n);
		float B = -n*f / (f-n);

		return Mat44(
				DofA,	0,	0,	0,
				0,		d,	0,	0,
				0,		0,	A,	B,
				0,		0,	1,	0
				) ;
	}

	//------------------------------------------------------------------------
	// d3d left handed
	inline Mat44 MakeOrthogonalMatrix(float l, float t, float r, float b, float n, float f)
	{
		return Mat44(
			2.f/(r-l),	0,			0,	(l+r)/(l-r),
			0,			2.f/(t-b),	0,	(t+b)/(b-t),
			0,			0,			1.f/(f-n),	n/(n-f),
			0,			0,			0,			1.f);
	}

	inline Vec2 operator/(const Vec2& a, const Vec2I b)
	{
		return Vec2(a.x / (float)b.x, a.y / (float)b.y);
	}

	inline Vec3 CleanNegativeZero(const Vec3& a)
	{
		return Vec3(abs(a.x) < EPSILON ? 0.f : a.x,
			abs(a.y) < EPSILON ? 0.f : a.y,
			abs(a.z) < EPSILON ? 0.f : a.z);
	}
}